package net.expectx.common.single.util;


import com.google.common.collect.Maps;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import net.expectx.common.single.base.BaseResult;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.*;

import java.io.*;
import java.util.ArrayList;
import java.util.Map;

/**
 * @author lijian
 * PDF生成工具
 */
public class PdfUtil {
    public static final String PDF_TEMPLATE_FIELD_TYPE_TEXT="text:";
    public static final String PDF_TEMPLATE_FIELD_TYPE_IMAGE="image:";
    /**
     * 生成PDF
     * @param templatePath
     * @param newPdfPath
     * @param reportData
     * @return
     */
    public static BaseResult generalPdfByTemplate(String templatePath, String newPdfPath, Map reportData, Boolean isEncryption, String password) {
        Boolean flag=false;
        String msg=null;
        try {
            PdfReader reader = new PdfReader(templatePath);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PdfStamper stamper = new PdfStamper(reader, bos);
            PdfContentByte under = stamper.getUnderContent(1);
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
            fontList.add(bf);
            AcroFields fields = stamper.getAcroFields();
            fields.setSubstitutionFonts(fontList);
            fillData(stamper,fields, reportData);
            stamper.setFormFlattening(true);
            stamper.close();
            OutputStream fos = new FileOutputStream(newPdfPath);
            fos.write(bos.toByteArray());
            fos.flush();
            fos.close();
            bos.close();
            if (isEncryption){
                pdfEncryption(password,newPdfPath);
            }
            flag=true;
        }catch (Exception e){
            msg=e.getLocalizedMessage();
        }
        return new BaseResult(flag,msg,null);
    }
    /**
     * 填充模板
     * @param fields
     * @param data
     */
    public static void fillData(PdfStamper stamper,AcroFields fields, Map<String, String> data)throws IOException,DocumentException{
        for (String key : data.keySet()) {
            if (key.split(":").length==2){
                String [] keys=key.split(":");
                if ("image".equals(keys[0])){
                    String value = data.get(key);
                    int pageNo = fields.getFieldPositions(keys[1]).get(0).page;
                    com.itextpdf.text.Rectangle rectangle = fields.getFieldPositions(keys[1]).get(0).position;
                    float x = rectangle.getLeft();
                    float y = rectangle.getBottom();
                    float width = rectangle.getWidth();
                    float height = rectangle.getHeight();
                    // 读图片
                    com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(value);
                    // 获取操作的页面
                    PdfContentByte pdfContentByte = stamper.getOverContent(pageNo);
                    // 根据域的大小缩放图片
                    image.scaleToFit(width, height);
                    // 添加图片
                    image.setAbsolutePosition(x, y);
                    pdfContentByte.addImage(image);
                }else{
                    String value = data.get(key);
                    // 为字段赋值,注意字段名称是区分大小写的
                    fields.setField(keys[1], value);
                }
            }else{
                throw new DocumentException("map Key格式不正确");
            }
        }
    }

    /**
     * PDF加密
     * @param password
     * @param filePath
     * @throws Exception
     */
    public static void pdfEncryption(String password,String filePath)throws Exception{
        PDDocument load = PDDocument.load(new File(filePath));
        AccessPermission permissions = new AccessPermission();
        permissions.setCanExtractContent(false);
        permissions.setCanModify(false);
        permissions.setCanAssembleDocument(true);
        StandardProtectionPolicy p = new StandardProtectionPolicy(password , password, permissions);
        SecurityHandler sh = new StandardSecurityHandler(p);
        sh.prepareDocumentForEncryption(load);
        PDEncryption encryptionOptions= new PDEncryption();
        encryptionOptions.setSecurityHandler(sh);
        load.setEncryptionDictionary(encryptionOptions);
        load.save(filePath);
    }
    public static void main(String [] args) throws Exception {
        String templatePath = "D:\\A\\titifootball-v0.2\\titifootball\\titifootball-organization\\src\\main\\webapp\\resources\\template\\pdf-template.pdf";
        Map<String, String> reportData =  Maps.newHashMapWithExpectedSize(7);
        reportData.put(PDF_TEMPLATE_FIELD_TYPE_TEXT+"PI01", "李磊");
        reportData.put(PDF_TEMPLATE_FIELD_TYPE_TEXT+"PI04", "2018年1月12日-2018年5月12日");
        reportData.put(PDF_TEMPLATE_FIELD_TYPE_TEXT+"PI02", "2018年5月18日");
        reportData.put(PDF_TEMPLATE_FIELD_TYPE_IMAGE+"qrcode", "d:\\qrcode.jpg");
        System.out.println(generalPdfByTemplate(templatePath,"d:\\result.pdf",reportData,true,"123456"));
        System.out.println(new File("d:\\result.pdf").setExecutable(true));
    }
}
